using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

using OrbitOne.Logging.Core;
using OrbitOne.Feed.Domain;
using OrbitOne.Feed.Interfaces;

using Spring.Context;
using Spring.Context.Support;

namespace OrbitOne.Feed.Handlers {
    /// <summary>
    /// The abstract base base class for all writers.
    /// Currently one for .rss feeds and one for .atom feeds
    /// </summary>
    internal abstract class AbstractHandler : IHttpHandler {
        #region Members :
        static LoggingManager _logManager = LoggingManager.Instance.CreateLogger(typeof(AbstractHandler));
        #endregion Members
        #region Properties :
        public bool IsReusable {
            get { return false; }
        }
        #endregion Properties 
        #region Methods :
        /// <summary>
        /// Parses the name of the feed.
        /// </summary>
        /// <returns></returns>
        private String ParseFeedName() {
            String url = HttpContext.Current.Request.Url.ToString();
            String feedName = url.Substring(url.LastIndexOf("/") + 1, url.LastIndexOf(".") - url.LastIndexOf("/") - 1);
            return feedName.ToLower();
        }
        /// <summary>
        /// Loads the web feed data through the Spring.NET IOC container.
        /// </summary>
        /// <returns></returns>
        private WebFeed LoadWebFeedData() {
            try {
                IApplicationContext applicationContext = ContextRegistry.GetContext();
                IWebFeedDataLoader webfeeddataLoader = (IWebFeedDataLoader)applicationContext.GetObject(this.ParseFeedName());
                return webfeeddataLoader.DoLoad();
            } catch (Exception exception) {
                _logManager.WriteError(exception);
            }

            return null;
        }
        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"></see> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
        public void ProcessRequest(HttpContext context) {
            WebFeed webFeed = this.LoadWebFeedData();
            if (webFeed == null) return;
            AbstractWriter feedGenerator = CreateWriter(webFeed);
            context.Response.ContentType = "application/xml";
            feedGenerator.WriteFeed();
            ManageCache(context);
        }
        /// <summary>
        /// Sets output caching to 1 days.
        /// </summary>
        /// <param name="context">The context.</param>
        private static void ManageCache(HttpContext context) {
            context.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
            context.Response.Cache.SetExpires(DateTime.Now.AddDays(1));
        }
        /// <summary>
        /// Factory method for creating Output writers either RSS,ATOM or podcast.
        /// </summary>
        /// <param name="webFeed">The web feed.</param>
        /// <returns></returns>
        protected abstract AbstractWriter CreateWriter(WebFeed webFeed);
        #endregion Methods 
    }

}
